package com.example.tool.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Objects;

public class AES {
  // 偏移量iv
  private static final String ivKey = "M4A1_AK47_AWM_UN";

  private static SecretKeySpec secretKeySpec(String key) {
    byte[] keyBytes = key.getBytes();
    // 创建一个空的16位字节数组（默认值为0）
    byte[] bytes = new byte[16];
    for (int i = 0; i < keyBytes.length && i < bytes.length; i++) {
      bytes[i] = keyBytes[i];
    }
    return new SecretKeySpec(bytes, "AES");
  }

  public static String encryption(String key, String content) throws Exception {
    SecretKeySpec secretKeySpec = secretKeySpec(key);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec iv = new IvParameterSpec(ivKey.getBytes());
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv);
    byte[] result = cipher.doFinal(content.getBytes());
    return parseByte2HexStr(result);
  }

  public static String decrypt(String key, String content) throws Exception {
    SecretKeySpec secretKeySpec = secretKeySpec(key);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec iv = new IvParameterSpec(ivKey.getBytes());
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv);
    byte[] result = cipher.doFinal(Objects.requireNonNull(parseHexStr2Byte(content)));
    return new String(result);
  }


  /**
   * 二进制转换成16进制，加密后的字节数组不能直接转换为字符串
   * @param buf 需要转换的字节数组
   */
  static String parseByte2HexStr(byte[] buf) {
    StringBuilder sb = new StringBuilder();
    for (byte b : buf) {
      String hex = Integer.toHexString(b & 0xFF);
      if (hex.length() == 1) {
        hex = '0' + hex;
      }
      sb.append(hex.toUpperCase());
    }
    return sb.toString();
  }

  /**
   * 16进制转换成二进制
   * @param hexStr 需要转换的16进制的字符串
   * @return 返回字节数组
   */
  static byte[] parseHexStr2Byte(String hexStr) {
    if (hexStr.isEmpty()) {
      return null;
    }
    byte[] result = new byte[hexStr.length() / 2];
    for (int i = 0; i < hexStr.length() / 2; i++) {
      int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
      int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
      result[i] = (byte) (high * 16 + low);
    }
    return result;
  }
}
